package com.xavier.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.xavier.constants.RedisKey;
import com.xavier.vo.UserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class UserUtil {
    private static final long TIMEOUT_MINUTES = 60;

    public static UserInfoVO getUserInfo() {
        String token = getToken();
        if (StrUtil.isNotBlank(token)) {
            log.info("user token={}", token);
            String userJson = RedisUtil.get(RedisKey.getTokenKey(token));
            if (ObjectUtil.isNotEmpty(userJson)) {
                return JSON.parseObject(userJson, UserInfoVO.class);
            }
        }
        return null;
    }


    /**
     * 获取登录凭证
     *
     * @return 登录凭证
     */
    public static String getToken() {
        HttpServletRequest request = ServletUtil.getRequest();
        return request.getHeader("Authorization");
    }

    /**
     * 设置用户信息
     *
     * @param userInfoVO
     */
    public static String setRedisUser(UserInfoVO userInfoVO) {
        if (ObjectUtil.isEmpty(userInfoVO.getToken())) {
            userInfoVO.setToken(RandomUtil.randomString(RandomUtil.BASE_CHAR, 24).toLowerCase());
        }
        // 超时时间
        userInfoVO.setTimeout(LocalDateTime.now().plusMinutes(TIMEOUT_MINUTES));
        // 设置用户缓存
        String userKey = RedisKey.getTokenKey(userInfoVO.getToken());
        // token 用户信息
        String userInfoStr = JSON.toJSONString(userInfoVO);
        RedisUtil.set(userKey, userInfoStr, TimeUnit.MINUTES, TIMEOUT_MINUTES);
        return userInfoVO.getToken();
    }

    /**
     * 重设token过期时间
     */
    public static void expire(UserInfoVO userInfoVO) {
        LocalDateTime timeout = LocalDateTime.now().plusMinutes(TIMEOUT_MINUTES);
        Duration between = Duration.between(userInfoVO.getTimeout(), timeout);
        long minutes = between.toMinutes();
        if (minutes < TIMEOUT_MINUTES / 2) {
            userInfoVO.setTimeout(timeout);
            setRedisUser(userInfoVO);
        }

    }


}
